﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

using GalaSoft.MvvmLight.Messaging;

using NetBay.Core.BusinessEntities;
using NetBay.Core.BusinessEntities.Workflow;

using Rio.Framework.Pages;
using Rio.Framework.Pages.Controls;
using Rio.Framework.Pages.CriteriaControls;
using Rio.Manager.Application.Extensions;
using Rio.Manager.Application.Utils;
using Rio.Manager.Application.ViewModel.FolderTypeAdministration;

using Telerik.Windows.Controls;
using Rio.Manager.Application.Controls;
using Rio.Framework.Pages.ChildWindows;

namespace Rio.Manager.Application.Views
{
    public partial class NewWorkflowTabView : UserControl
    {
        #region Constructors

        public NewWorkflowTabView()
        {
            InitializeComponent();

            Unloaded += (s, e) =>
            {
                Messenger.Default.Unregister<RioDialogMessage>(this, AskConfirmationBeforeDeletion);
                Messenger.Default.Unregister<NotificationMessageAction<List<Group>>>(this, ShowGroupsWindow);
                Messenger.Default.Unregister<NotificationMessageAction<Index>>(this, ShowIndexSelectionWindow);
                Messenger.Default.Unregister<NotificationMessageAction<DateTime>>(this, ShowSelectionDateTimePickerWindow);
                Messenger.Default.Unregister<NotificationMessage<ObservableCollection<WorkflowAction>>>(this, SetSelectedActions);
                Messenger.Default.Unregister<NotificationMessage<ObservableCollection<WorkflowCondition>>>(this, SetSelectedConditions);
                Messenger.Default.Unregister<NotificationMessageAction<string>>(this, OpenChildWorkflowRulesEditorWindow);
            };

            Messenger.Default.Register<RioDialogMessage>(this, AskConfirmationBeforeDeletion);
            Messenger.Default.Register<NotificationMessageAction<List<Group>>>(this, ShowGroupsWindow);
            Messenger.Default.Register<NotificationMessageAction<Index>>(this, ShowIndexSelectionWindow);
            Messenger.Default.Register<NotificationMessageAction<DateTime>>(this, ShowSelectionDateTimePickerWindow);
            Messenger.Default.Register<NotificationMessage<ObservableCollection<WorkflowAction>>>(this, SetSelectedActions);
            Messenger.Default.Register<NotificationMessage<ObservableCollection<WorkflowCondition>>>(this, SetSelectedConditions);
            Messenger.Default.Register<NotificationMessageAction<string>>(this, OpenChildWorkflowRulesEditorWindow);
        }

        #endregion Constructors

        #region Methods

        /// <summary>
        /// Opens the child workflow window.
        /// </summary>
        /// <param name="msg">The MSG.</param>
        private void OpenChildWorkflowRulesEditorWindow(NotificationMessageAction<string> msg)
        {
            WorkflowRulesEditorChildWindow w = new WorkflowRulesEditorChildWindow();
            w.LoadRulesDocument(msg.Notification);

            w.Closed += (sender, e) =>
            {
                WorkflowRulesEditorChildWindow source = sender as WorkflowRulesEditorChildWindow;

                if (source.DialogResult == true)
                {
                    msg.Execute(source.Rules);
                }
            };
            w.ShowDialog();
        }

        /// <summary>
        /// Handles the SelectionChanged event of the ActionsRadGridView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.Controls.SelectionChangeEventArgs"/> instance containing the event data.</param>
        private void ActionsRadGridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
        {
            ((NewWorkflowTabViewModel)DataContext).SelectedActions = new ObservableCollection<WorkflowAction>(((RadGridView)sender).SelectedItems.Cast<WorkflowAction>());
        }

        /// <summary>
        /// Asks the confirmation before deletion.
        /// </summary>
        /// <param name="msg">The MSG.</param>
        private void AskConfirmationBeforeDeletion(RioDialogMessage msg)
        {
            MessageBoxChildWindow confirmWindow = new MessageBoxChildWindow(msg.Caption, msg.Content, msg.Button, msg.Icon);

            confirmWindow.Closed += (sender, e) =>
            {
                if (confirmWindow.DialogResult == true)
                {
                    msg.ProcessCallback(MessageBoxResult.Yes);
                }
                else
                {
                    msg.ProcessCallback(MessageBoxResult.No);
                }
            };

            confirmWindow.Show();
        }

        /// <summary>
        /// Handles the SelectionChanged event of the ConditionsRadGridView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.Controls.SelectionChangeEventArgs"/> instance containing the event data.</param>
        private void ConditionsRadGridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
        {
            if (((RadGridView)sender).SelectedItems != null && ((RadGridView)sender).SelectedItems.Count > 0 && ((RadGridView)sender).SelectedItems[0].GetType() == typeof(WorkflowAction))
            {
                var conditions = new List<WorkflowCondition>();
                var actions = ((RadGridView)sender).SelectedItems.Cast<WorkflowAction>();
                foreach (var item in actions)
                {
                    conditions.Add(item.ConvertToWorkflowCondition());
                }

                ((NewWorkflowTabViewModel)DataContext).SelectedConditions = new ObservableCollection<WorkflowCondition>(conditions);
            }
            else
            {
                ((NewWorkflowTabViewModel)DataContext).SelectedConditions = new ObservableCollection<WorkflowCondition>(((RadGridView)sender).SelectedItems.Cast<WorkflowCondition>());
            }
        }

        /// <summary>
        /// Sets the selected actions.
        /// </summary>
        /// <param name="msg">The MSG.</param>
        private void SetSelectedActions(NotificationMessage<ObservableCollection<WorkflowAction>> msg)
        {
            ActionsRadGridView.SelectedItems.Clear();

            foreach (var workflowAction in msg.Content)
            {
                foreach (var item in ActionsRadGridView.Items)
                {
                    WorkflowAction action = item as WorkflowAction;

                    if(action != null && workflowAction.ActionOrConditionId == action.ActionOrConditionId)
                    {
                        ActionsRadGridView.SelectedItems.Add(item);
                    }
                }
            }
        }

        /// <summary>
        /// Sets the selected actions.
        /// </summary>
        /// <param name="msg">The MSG.</param>
        private void SetSelectedConditions(NotificationMessage<ObservableCollection<WorkflowCondition>> msg)
        {
            ConditionsRadGridView.SelectedItems.Clear();

            foreach (var condition in msg.Content)
            {
                foreach (var item in ConditionsRadGridView.Items)
                {
                    WorkflowCondition cond = item as WorkflowCondition;

                    if (cond != null && condition.ActionOrConditionId == cond.ActionOrConditionId)
                    {
                        ConditionsRadGridView.SelectedItems.Add(item);
                    }
                }
            }
        }

        /// <summary>
        /// Shows the groups window.
        /// </summary>
        /// <param name="msg">The MSG.</param>
        private void ShowGroupsWindow(NotificationMessageAction<List<Group>> msg)
        {
            NewWorkflowTabViewModel context = ((NewWorkflowTabViewModel)DataContext);

            GroupWindowBase groupWindow = null;
            List<long> selectedGroupsId = msg.Sender as List<long>;
            List<Group> selectedGroups = msg.Target as List<Group>;

            if (context.CurrentWorkflowDefinition.IsHierarchical)
            {
                if (selectedGroupsId != null && selectedGroupsId.Count > 0)
                {
                    groupWindow = new ChoiceGroupWindow(selectedGroupsId);
                }
                else
                {
                    groupWindow = new ChoiceGroupWindow();
                }
            }
            else
            {
                if (selectedGroupsId != null && selectedGroupsId.Count > 0)
                {
                    groupWindow = new GroupFilterWindow(selectedGroupsId);
                }
                else
                {
                    groupWindow = new GroupFilterWindow();
                }
            }


            groupWindow.Closed += delegate(object sender, Telerik.Windows.Controls.WindowClosedEventArgs e)
            {
                GroupWindowBase g = ((GroupWindowBase)sender);

                if (g.DialogResult == true)
                {
                    msg.Execute(g.m_szSelectedItems);
                }
                else
                {
                    msg.Execute(selectedGroups);
                }
            };

            groupWindow.ShowDialog();

        }

        /// <summary>
        /// Shows the index selection window.
        /// </summary>
        /// <param name="msg">The MSG.</param>
        private void ShowIndexSelectionWindow(NotificationMessageAction<Index> msg)
        {
            SelectionRecipientIndexChildWindow selectionRecipientIndexChildWindow = new SelectionRecipientIndexChildWindow()
            {
                Indexes = new ObservableCollection<Index>(msg.Sender as List<Index>),
                SelectedIndexIdentifier = msg.Target == null ? -1 : (msg.Target as Index).Indentifier
            };

            selectionRecipientIndexChildWindow.Closed += (o, e) =>
            {
                SelectionRecipientIndexChildWindow windowSource = o as SelectionRecipientIndexChildWindow;

                if (windowSource.DialogResult == true)
                {
                    msg.Execute(windowSource.SelectedIndex);
                }
                else
                {
                    msg.Execute(msg.Target as Index);
                }
            };

            selectionRecipientIndexChildWindow.ShowDialog();
        }

        /// <summary>
        /// Shows the selection date time picker window.
        /// </summary>
        /// <param name="msg">The MSG.</param>
        private void ShowSelectionDateTimePickerWindow(NotificationMessageAction<DateTime> msg)
        {
            DateTimePickerChildWindow dateTimePickerChildWindow = new DateTimePickerChildWindow()
            {
                DescriptionText = "Attention : Afin d'enregistrer les modifications, l'ancien workflow sera désactivé à la date spécifée et un nouveau sera créé.",
                DateTimePickerText = "Date de désactivation :",
                SelectedDateTime = (DateTime)msg.Sender
            };

            dateTimePickerChildWindow.Closed += (s, e) =>
            {
                if (((DateTimePickerChildWindow)s).DialogResult == true)
                {
                    msg.Execute((s as DateTimePickerChildWindow).SelectedDateTime);
                }
            };

            dateTimePickerChildWindow.ShowDialog();
        }

        #endregion Methods
    }
}